package cn.cttic.order.service.impl;

import cn.cttic.app.api.enums.InstallOrderStatus;
import cn.cttic.common.core.exception.order.OrderException;
import cn.cttic.common.core.utils.BeanCopyUtils;
import cn.cttic.common.core.utils.MapstructUtils;
import cn.cttic.common.core.utils.StringUtils;
import cn.cttic.common.mybatis.core.page.TableDataInfo;
import cn.cttic.common.mybatis.core.page.PageQuery;
import cn.cttic.common.satoken.utils.LoginHelper;
import cn.cttic.order.api.domain.BaseInstallOrder;
import cn.cttic.order.api.domain.BaseInstallOrderMainPage;
import cn.cttic.order.api.domain.BaseInstallOrderSubPage;
import cn.cttic.order.api.domain.bo.AuditOrderProcessBo;
import cn.cttic.order.api.domain.bo.MainPageOcrBo;
import cn.cttic.order.api.domain.bo.SubPageOcrBo;
import cn.cttic.order.api.domain.vo.BaseInstallOrderMainPageVo;
import cn.cttic.order.api.domain.vo.BaseInstallOrderSubPageVo;
import cn.cttic.order.config.BaiduAipClient;
import cn.cttic.order.mapper.BaseInstallOrderMainPageMapper;
import cn.cttic.order.mapper.BaseInstallOrderMapper;
import cn.cttic.order.mapper.BaseInstallOrderSubPageMapper;
import cn.cttic.resource.api.RemoteFileService;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.json.JSONObject;
import org.springframework.stereotype.Service;
import cn.cttic.order.api.domain.bo.BaseInstallOrderProcessBo;
import cn.cttic.order.api.domain.vo.BaseInstallOrderProcessVo;
import cn.cttic.order.api.domain.BaseInstallOrderProcess;
import cn.cttic.order.mapper.BaseInstallOrderProcessMapper;
import cn.cttic.order.service.IBaseInstallOrderProcessService;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Collection;

/**
 * 安装数据Service业务层处理
 *
 * @author Times.Studio
 * @date 2024-09-17
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class BaseInstallOrderProcessServiceImpl implements IBaseInstallOrderProcessService {

    private final BaseInstallOrderProcessMapper baseMapper;
    private final BaseInstallOrderMapper baseInstallOrderMapper;

    @DubboReference
    private RemoteFileService remoteFileService;

    private final BaiduAipClient baiduAipClient;

    private final BaseInstallOrderMainPageMapper baseInstallOrderMainPageMapper;
    private final BaseInstallOrderSubPageMapper baseInstallOrderSubPageMapper;

    @Override
    public String getOrderImei(String orderId) {
        List<BaseInstallOrderProcess> list = baseMapper.selectList(
            new LambdaQueryWrapper<BaseInstallOrderProcess>().eq(BaseInstallOrderProcess::getInstallOrderId, orderId)
        );
        log.info("查询到数据列表： {}", list);
        for (BaseInstallOrderProcess process : list) {
            if (process.getStepId().equals("10010") && StrUtil.isNotBlank(process.getInteriorData())) {
                log.info("订单： {} IMEI是 {}", orderId, process.getInteriorData());
                return process.getInteriorData();
            }
        }
        log.info("订单： {} 无IMEI", orderId);
        return null;
    }

    @Override
    public String getOrderIdByImei(String imei) {
        List<BaseInstallOrderProcess> list = baseMapper.selectList(
            new LambdaQueryWrapper<BaseInstallOrderProcess>().eq(BaseInstallOrderProcess::getInteriorData, imei)
                .orderByDesc(BaseInstallOrderProcess::getCreateTime)
        );
        log.info("查询到数据列表： {}", list);
        for (BaseInstallOrderProcess process : list) {
            if (StrUtil.isNotBlank(process.getInstallOrderId())) {
                return process.getInstallOrderId();
            }
        }
        log.error("IMEI {} 未找到匹配订单", imei);
        return null;
    }
    /**
     * 主证件识别
     *
     * @param bo
     * @return
     */
    @Override
    public BaseInstallOrderMainPageVo mainPageOcr(MainPageOcrBo bo) {
        log.info("[百度OCR识别(行驶证主页）][开始]");
        log.info("[百度OCR识别(行驶证主页）][入参][{}]", bo);

        try {
            // 传入可选参数调用接口
            HashMap<String, String> options = new HashMap<String, String>();
            options.put("vehicle_license_side", "front");

            String ossUrl = remoteFileService.selectUrlByIds(bo.getOssId());
            byte[] bytes = remoteFileService.download(bo.getOssId());

            log.info("[百度OCR识别(行驶证主页）][请求地址参数][{}][{}]", ossUrl, options);

            JSONObject jsonObject = baiduAipClient.createAipOcr().vehicleLicense(bytes, options);

            log.info("[百度OCR识别(行驶证主页）][返回][{}]", jsonObject.toString());

            if (jsonObject != null) {
                if (jsonObject.has("words_result")) {
                    JSONObject wordsResult = jsonObject.getJSONObject("words_result");

                    boolean isNew = true;
                    BaseInstallOrderMainPage mainPage = null;
                    List<BaseInstallOrderMainPage> mainPageList = baseInstallOrderMainPageMapper.selectList(
                        new LambdaQueryWrapper<BaseInstallOrderMainPage>().eq(BaseInstallOrderMainPage::getInstallOrderId, bo.getOrderId())
                    );

                    if (CollUtil.isNotEmpty(mainPageList)) {
                        isNew = false;
                        mainPage = mainPageList.get(0);
                    } else {
                        mainPage = new BaseInstallOrderMainPage();
                        mainPage.setInstallOrderId(bo.getOrderId());
                    }
                    mainPage.setOssId(bo.getOssId());
                    mainPage.setOssUrl(ossUrl);

                    if (wordsResult != null) {
                        if (wordsResult.has("车辆识别代号")) {
                            if (wordsResult.getJSONObject("车辆识别代号").has("words")) {
                                mainPage.setVehicleId(wordsResult.getJSONObject("车辆识别代号").getString("words"));
                            }
                        }

                        if (wordsResult.has("住址")) {
                            if (wordsResult.getJSONObject("住址").has("words")) {
                                mainPage.setAddress(wordsResult.getJSONObject("住址").getString("words"));
                            }
                        }

                        if (wordsResult.has("发证单位")) {
                            if (wordsResult.getJSONObject("发证单位").has("words")) {
                                mainPage.setIssuedBy(wordsResult.getJSONObject("发证单位").getString("words"));
                            }
                        }

                        if (wordsResult.has("发证日期")) {
                            if (wordsResult.getJSONObject("发证日期").has("words")) {
                                mainPage.setIssuedDate(wordsResult.getJSONObject("发证日期").getString("words"));
                            }
                        }

                        if (wordsResult.has("品牌型号")) {
                            if (wordsResult.getJSONObject("品牌型号").has("words")) {
                                mainPage.setBrandModel(wordsResult.getJSONObject("品牌型号").getString("words"));
                            }
                        }

                        if (wordsResult.has("车辆类型")) {
                            if (wordsResult.getJSONObject("车辆类型").has("words")) {
                                mainPage.setVehicleType(wordsResult.getJSONObject("车辆类型").getString("words"));
                            }
                        }

                        if (wordsResult.has("所有人")) {
                            if (wordsResult.getJSONObject("所有人").has("words")) {
                                mainPage.setBelongTo(wordsResult.getJSONObject("所有人").getString("words"));
                            }
                        }

                        if (wordsResult.has("使用性质")) {
                            if (wordsResult.getJSONObject("使用性质").has("words")) {
                                mainPage.setUsingProperty(wordsResult.getJSONObject("使用性质").getString("words"));
                            }
                        }

                        if (wordsResult.has("发动机号码")) {
                            if (wordsResult.getJSONObject("发动机号码").has("words")) {
                                mainPage.setEngineNo(wordsResult.getJSONObject("发动机号码").getString("words"));
                            }
                        }

                        if (wordsResult.has("号牌号码")) {
                            if (wordsResult.getJSONObject("号牌号码").has("words")) {
                                mainPage.setCarNo(wordsResult.getJSONObject("号牌号码").getString("words"));
                            }
                        }

                        if (wordsResult.has("注册日期")) {
                            if (wordsResult.getJSONObject("注册日期").has("words")) {
                                mainPage.setRegisterDate(wordsResult.getJSONObject("注册日期").getString("words"));
                            }
                        }
                    }

                    int ret = -1;
                    if (isNew) {
                        ret = baseInstallOrderMainPageMapper.insert(mainPage);
                    } else {
                        ret = baseInstallOrderMainPageMapper.updateById(mainPage);
                    }
                    if (ret > 0) {
                        log.info("[百度OCR识别(行驶证主页）][更新库数据成功][{}]", jsonObject.toString());
                    }
                    return BeanCopyUtils.copy(mainPage, BaseInstallOrderMainPageVo.class);
                }
            }
            return null;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 副证件识别
     *
     * @param bol
     * @return
     */
    @Override
    public BaseInstallOrderSubPageVo subPageOcr(SubPageOcrBo bo) {
        log.info("[百度OCR识别(行驶证副页）][开始]");
        log.info("[百度OCR识别(行驶证副页）][入参][{}]", bo);

        try {
            // 传入可选参数调用接口
            HashMap<String, String> options = new HashMap<String, String>();
            options.put("vehicle_license_side", "back");

            String ossUrl = remoteFileService.selectUrlByIds(bo.getOssId());
            byte[] bytes = remoteFileService.download(bo.getOssId());

            log.info("[百度OCR识别(行驶证副页）][请求地址参数][{}][{}]", ossUrl, options);

            JSONObject jsonObject = baiduAipClient.createAipOcr().vehicleLicense(bytes, options);

            log.info("[百度OCR识别(行驶证副页）][返回][{}]", jsonObject.toString());
            if (jsonObject != null) {
                if (jsonObject.has("words_result")) {
                    JSONObject wordsResult = jsonObject.getJSONObject("words_result");

                    boolean isNew = true;
                    BaseInstallOrderSubPage subPage = null;
                    List<BaseInstallOrderSubPage> subPageList = baseInstallOrderSubPageMapper.selectList(
                        new LambdaQueryWrapper<BaseInstallOrderSubPage>().eq(BaseInstallOrderSubPage::getInstallOrderId, bo.getOrderId())
                    );

                    if (CollUtil.isNotEmpty(subPageList)) {
                        isNew = false;
                        subPage = subPageList.get(0);
                    } else {
                        subPage = new BaseInstallOrderSubPage();
                        subPage.setInstallOrderId(bo.getOrderId());
                    }
                    subPage.setOssId(bo.getOssId());
                    subPage.setOssUrl(ossUrl);

                    if (wordsResult != null) {
                        if (wordsResult.has("检验记录")) {
                            if (wordsResult.getJSONObject("检验记录").has("words")) {
                                subPage.setInspectionRecord(wordsResult.getJSONObject("检验记录").getString("words"));
                            }
                        }

                        if (wordsResult.has("核定载质量")) {
                            if (wordsResult.getJSONObject("核定载质量").has("words")) {
                                subPage.setApprovedLoad(wordsResult.getJSONObject("核定载质量").getString("words"));
                            }
                        }

                        if (wordsResult.has("整备质量")) {
                            if (wordsResult.getJSONObject("整备质量").has("words")) {
                                subPage.setCurbWeight(wordsResult.getJSONObject("整备质量").getString("words"));
                            }
                        }

                        if (wordsResult.has("外廓尺寸")) {
                            if (wordsResult.getJSONObject("外廓尺寸").has("words")) {
                                subPage.setOverallDimensions(wordsResult.getJSONObject("外廓尺寸").getString("words"));
                            }
                        }

                        if (wordsResult.has("核定载人数")) {
                            if (wordsResult.getJSONObject("核定载人数").has("words")) {
                                subPage.setApprovedCapacity(wordsResult.getJSONObject("核定载人数").getString("words"));
                            }
                        }

                        if (wordsResult.has("总质量")) {
                            if (wordsResult.getJSONObject("总质量").has("words")) {
                                subPage.setTotalQuality(wordsResult.getJSONObject("总质量").getString("words"));
                            }
                        }

                        if (wordsResult.has("燃油类型")) {
                            if (wordsResult.getJSONObject("燃油类型").has("words")) {
                                subPage.setFuleType(wordsResult.getJSONObject("燃油类型").getString("words"));
                            }
                        }

                        if (wordsResult.has("准牵引总质量")) {
                            if (wordsResult.getJSONObject("准牵引总质量").has("words")) {
                                subPage.setTractionTotalQuality(wordsResult.getJSONObject("准牵引总质量").getString("words"));
                            }
                        }

                        if (wordsResult.has("档案编号")) {
                            if (wordsResult.getJSONObject("档案编号").has("words")) {
                                subPage.setDocumentNo(wordsResult.getJSONObject("档案编号").getString("words"));
                            }
                        }

                        if (wordsResult.has("号牌号码")) {
                            if (wordsResult.getJSONObject("号牌号码").has("words")) {
                                subPage.setCarNo(wordsResult.getJSONObject("号牌号码").getString("words"));
                            }
                        }

                        if (wordsResult.has("证芯编号")) {
                            if (wordsResult.getJSONObject("证芯编号").has("words")) {
                                subPage.setCaliber(wordsResult.getJSONObject("证芯编号").getString("words"));
                            }
                        }
                    }

                    int ret = -1;
                    if (isNew) {
                        ret = baseInstallOrderSubPageMapper.insert(subPage);
                    } else {
                        ret = baseInstallOrderSubPageMapper.updateById(subPage);
                    }
                    if (ret > 0) {
                        log.info("[百度OCR识别(行驶证副页）][更新库数据成功][{}]", jsonObject.toString());
                    }
                    return BeanCopyUtils.copy(subPage, BaseInstallOrderSubPageVo.class);
                }
            }
            return null;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 查询安装数据
     *
     * @param id 主键
     * @return 安装数据
     */
    @Override
    public BaseInstallOrderProcessVo queryById(String id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询安装数据
     *
     * @param bo@return 安装数据
     */
    @Override
    public BaseInstallOrderProcessVo updateFixOssId(BaseInstallOrderProcessBo bo) {
        if (StrUtil.isNotBlank(bo.getOssId())) {
            String fixOssUrl = remoteFileService.selectUrlByIds(bo.getFixOssId());
            bo.setFixOssUrl(fixOssUrl);
            if (baseMapper.updateById(BeanCopyUtils.copy(bo, BaseInstallOrderProcess.class)) > 0) {
                return BeanCopyUtils.copy(bo, BaseInstallOrderProcessVo.class);
            } else {
                throw new OrderException("更新修复照片失败");
            }
        } else {
            throw new OrderException("更新修复照片失败");
        }
    }

    /**
     * 分页查询安装数据列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 安装数据分页列表
     */
    @Override
    public TableDataInfo<BaseInstallOrderProcessVo> queryPageList(BaseInstallOrderProcessBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<BaseInstallOrderProcess> lqw = buildQueryWrapper(bo);
        Page<BaseInstallOrderProcessVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的安装数据列表
     *
     * @param bo 查询条件
     * @return 安装数据列表
     */
    @Override
    public List<BaseInstallOrderProcessVo> queryList(BaseInstallOrderProcessBo bo) {
        LambdaQueryWrapper<BaseInstallOrderProcess> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    @Override
    public BaseInstallOrderProcessVo auditOrderProcess(AuditOrderProcessBo bo) {
        BaseInstallOrderProcess process = baseMapper.selectById(bo.getProcessId());

        process.setInteriorData(bo.getProcessedData());
        process.setAuditBy(LoginHelper.getUserId().toString());
        process.setAuditStatus(bo.getAuditStatus());
        process.setAuditReason(bo.getAuditReason());

        // 主页
        if (bo.getProcessStepId().equals("10015")) {
            if (StrUtil.isNotBlank(bo.getProcessedData())) {
                BaseInstallOrderMainPage mainPage = JSON.parseObject(bo.getProcessedData(), BaseInstallOrderMainPage.class);
                if (mainPage != null) {
                    boolean isNew = StrUtil.isBlank(mainPage.getId());
                    mainPage.setInstallOrderId(process.getInstallOrderId());
                    int ret = -1;
                    if (isNew) {
                        ret = baseInstallOrderMainPageMapper.insert(mainPage);
                    } else {
                        ret = baseInstallOrderMainPageMapper.updateById(mainPage);
                    }
                    if (ret > 0) {
                        log.info("[百度OCR识别(行驶证主页）][更新库数据成功][{}]", JSON.toJSONString(mainPage));
                    }
                }
            } else {
                log.error("[主数据为空]");
            }
        } else if (bo.getProcessStepId().equals("10020")) {
            if (StrUtil.isNotBlank(bo.getProcessedData())) {
                BaseInstallOrderSubPage subPage = JSON.parseObject(bo.getProcessedData(), BaseInstallOrderSubPage.class);
                if (subPage != null) {
                    boolean isNew = StrUtil.isBlank(subPage.getId());
                    subPage.setInstallOrderId(process.getInstallOrderId());
                    int ret = -1;
                    if (isNew) {
                        ret = baseInstallOrderSubPageMapper.insert(subPage);
                    } else {
                        ret = baseInstallOrderSubPageMapper.updateById(subPage);
                    }
                    if (ret > 0) {
                        log.info("[百度OCR识别(行驶证副页）][更新库数据成功][{}]", JSON.toJSONString(subPage));
                    }
                }
            } else {
                log.error("[主数据为空]");
            }
        }

        if (baseMapper.updateById(process) > 0){
            if (bo.getAuditStatus() == 2 && bo.getForceOrderFailed() == 1) {
                BaseInstallOrder order = baseInstallOrderMapper.selectById(process.getInstallOrderId());
                order.setVerifyReason(bo.getAuditReason());
                order.setVerifyStatus(2);
                order.setVerifyBy(LoginHelper.getUserId().toString());
                order.setStatus(InstallOrderStatus.PROBLEM.getValue());
                if (baseInstallOrderMapper.updateById(order) <= 0){
                    throw new OrderException(String.format("验收订单 %s 失败（更新）", process.getInstallOrderId()));
                }
            }
            return baseMapper.selectVoById(bo.getProcessId());
        } else {
            throw new OrderException(String.format("审核订单数据 %s 失败（更新）", bo.getProcessId()));
        }
    }

    private LambdaQueryWrapper<BaseInstallOrderProcess> buildQueryWrapper(BaseInstallOrderProcessBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<BaseInstallOrderProcess> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getInstallOrderId()), BaseInstallOrderProcess::getInstallOrderId, bo.getInstallOrderId());
        lqw.like(StringUtils.isNotBlank(bo.getStepGroupName()), BaseInstallOrderProcess::getStepGroupName, bo.getStepGroupName());
        lqw.eq(bo.getStepIndex() != null, BaseInstallOrderProcess::getStepIndex, bo.getStepIndex());
        lqw.like(StringUtils.isNotBlank(bo.getStepName()), BaseInstallOrderProcess::getStepName, bo.getStepName());
        lqw.eq(StringUtils.isNotBlank(bo.getStepId()), BaseInstallOrderProcess::getStepId, bo.getStepId());
        lqw.eq(StringUtils.isNotBlank(bo.getOssId()), BaseInstallOrderProcess::getOssId, bo.getOssId());
        lqw.eq(StringUtils.isNotBlank(bo.getOssUrl()), BaseInstallOrderProcess::getOssUrl, bo.getOssUrl());
        lqw.eq(StringUtils.isNotBlank(bo.getInteriorDataType()), BaseInstallOrderProcess::getInteriorDataType, bo.getInteriorDataType());
        lqw.eq(StringUtils.isNotBlank(bo.getInteriorData()), BaseInstallOrderProcess::getInteriorData, bo.getInteriorData());
        lqw.eq(bo.getAuditStatus() != null, BaseInstallOrderProcess::getAuditStatus, bo.getAuditStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getAuditBy()), BaseInstallOrderProcess::getAuditBy, bo.getAuditBy());
        lqw.eq(StringUtils.isNotBlank(bo.getAuditReason()), BaseInstallOrderProcess::getAuditReason, bo.getAuditReason());
        return lqw;
    }

    /**
     * 新增安装数据
     *
     * @param bo 安装数据
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(BaseInstallOrderProcessBo bo) {
        BaseInstallOrderProcess add = MapstructUtils.convert(bo, BaseInstallOrderProcess.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改安装数据
     *
     * @param bo 安装数据
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(BaseInstallOrderProcessBo bo) {
        BaseInstallOrderProcess update = MapstructUtils.convert(bo, BaseInstallOrderProcess.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(BaseInstallOrderProcess entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并批量删除安装数据信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }
}
